<template>
  <div class="rating-container">
    <!-- el-card -> 卡片组件，提供了整洁 & 富有层次感的容器 -->
    <el-card class="rating-card">
      <!-- 卡片头部 -> 评分管理四个字 -->
      <template #header>
        <div class="card-header">
          <span>评分管理</span>
        </div>
      </template>

      <!-- 卡片的主体是表格，用el-table组件 -->
      <!-- :data -> 是相应数据，使用的是ratingList数据, 下面表格项中的prop就是ratingList中的字段 -->
      <!-- style="width: 100%" -> 表格宽度为100%，border -> 表格边框 -->
      <el-table :data="ratingList" style="width: 100%" border>
        <!-- 第一列表格项 -->
        <!-- prop -> 表示数据项的字段 -->
        <!-- label -> 表示数据项的标题 -->
        <!-- width -> 表示数据项的宽度 -->
        <el-table-column prop="id" label="ID" width="80" />
        <!-- 第二列表格项 -->
        <el-table-column prop="name" label="项目名称" />
        <!-- 第三列表格项 -->
        <el-table-column prop="author" label="作者" width="120" />
        <!-- 第四列表格项 -->
        <el-table-column label="平均分" width="300">
          <template #default="{ row }">
            <!--
              el-rate -> 评分组件
              v-model -> 表示当前评分
              disabled -> 表示禁用
              max -> 表示最大评分
              show-score -> 表示显示评分
              text-color -> 表示文字颜色
              score-template -> 表示评分模板
            -->
            <el-rate
              v-model="row.averageScore"
              disabled
              :max="10"
              show-score
              text-color="#ff9900"
              score-template="{value}"
            />
          </template>
        </el-table-column>
        <!-- 第五列表格项 -->
        <el-table-column label="操作" width="180">
          <!-- 列表项模板，使用#default="{row}"，拿到当前行的数据，方便下面进行函数调用的时候参数使用 -->
          <template #default="{ row }">
            <!-- el-button -> 按钮组件，用于显示按钮 -->
            <!-- size -> 表示按钮的大小，这里设置为small，表示小按钮 -->
            <!-- type -> 表示按钮的类型，这里设置为primary，表示主要按钮 -->
            <!-- 评分按钮
              通过点击 按钮，调用showRatingDialog函数，传入当前行的数据，用于显示评分对话框
              设置初始化数据和ratingDialogVisible.value = true
            -->
            <el-button size="small" type="primary" @click="showRatingDialog(row)">评分</el-button>
            <!-- 详情按钮
              通过点击 按钮，调用showRatingDetails函数，传入当前行的数据，用于显示评分详情对话框
              设置初始化数据currentItemId.value = row.id
              设置初始化数据detailDialogVisible.value = true
            -->
            <el-button size="small" @click="showRatingDetails(row.id)">详情</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页组件 -> 用于分页 -->
      <!-- :current-page ->
        表示当前页码，这里绑定了pagination.currentPage
        pagination.currentPage是响应式数据，所以这里会自动更新
      -->
      <!-- :page-size ->
        表示每页显示的条数，这里绑定了pagination.pageSize
        pagination.pageSize是响应式数据，所以这里会自动更新
      -->
      <!-- :total ->
        表示总条数, 这里绑定了pagination.total
        pagination.total是响应式数据，所以这里会自动更新
      -->
      <!-- :page-sizes ->
        表示每页显示的条数，这里绑定了[5, 10, 20, 50]
        这个数组是静态数据，所以这里不会自动更新
      -->
      <!-- layout -> 表示分页布局，这里绑定了'total, sizes, prev, pager, next, jumper'-->
      <!-- @current-change ->
        表示当前页码改变时，调用fetchRatingList方法
        这个方法用于获取当前页码的数据
      -->
      <!-- @size-change ->
        表示每页显示的条数改变时，调用handleSizeChange方法
        这个方法用于 重置当前页码大小之后，获取当前页码的数据fetchReviewList
      -->
      <el-pagination
        class="pagination"
        v-model:current-page="pagination.currentPage"
        v-model:page-size="pagination.pageSize"
        :total="pagination.total"
        :page-sizes="[5, 10, 20, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        @current-change="fetchRatingList"
        @size-change="handleSizeChange"
      />
    </el-card>

    <!-- 评分对话框 -->
    <el-dialog v-model="ratingDialogVisible" :title="`为 ${currentItem?.name} 评分`" width="40%">
      <div class="rating-form">
        <!-- el-form -> 表单组件，用于显示表单, :model -> 双向绑定使用的数据结构是ratingForm, 评分和评论 -->
        <el-form :model="ratingForm" label-width="80px">
          <!-- 评分项 -->
          <el-form-item label="评分">
            <!-- el-rate -> 评分组件 -->
            <!-- v-model -> 双向绑定当前评分 -->
            <el-rate
              v-model="ratingForm.score"
              :colors="['#99A9BF', '#F7BA2A', '#FF9900']"
              :max="10"
              show-text
              text-template="{value}分"
            />
          </el-form-item>
          <!-- 评价项 -->
          <el-form-item label="评价">
            <!-- el-input -> 输入框组件，用于显示输入框 -->
            <!-- type -> 表示输入框的类型，这里设置为textarea，表示多行输入框 -->
            <!-- v-model -> 双向绑定当前评价 -->
            <el-input
              v-model="ratingForm.comment"
              type="textarea"
              :rows="4"
              placeholder="请输入评价内容"
            />
          </el-form-item>
        </el-form>
      </div>
      <!-- 底部，提交按钮和取消按钮 -->
      <!-- 如果是取消按钮，则直接关闭对话框 -->
      <!-- 如果是提交按钮，则调用submitRating方法 -->
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="ratingDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitRating">提交</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 评分详情对话框 -->
    <el-dialog v-model="detailDialogVisible" title="评分详情" width="60%">
      <!-- 评分详情组件, 向子组件传递当前行的id -->
      <rating-detail :item-id="currentItemId" />
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import type { RatingItem, RatingForm } from '@/api/types/rating'
import RatingDetail from './RatingDetail.vue'

// 评分列表数据
// 使用ref定义一个响应式数据，用于存储评分列表数据，后续在挂载的时候将调用后端的API接口获取数据
const ratingList = ref<RatingItem[]>([])
// 当前选中的评分项 -> 用于处理当前的评分项用
const currentItem = ref<RatingItem | null>(null)
// 当前评分项ID -> 用于定位当前的评分项
const currentItemId = ref<number>(0)

// 分页配置
const pagination = ref({
  currentPage: 1,
  pageSize: 10,
  total: 0
})

// 对话框控制
const ratingDialogVisible = ref<boolean>(false)
const detailDialogVisible = ref<boolean>(false)

// 评分表单
const ratingForm = ref<RatingForm>({
  score: 0,
  comment: ''
})

// 获取评分列表
const fetchRatingList = async () => {
  try {
    // 模拟数据
    const mockData: RatingItem[] = Array.from({ length: 10 }, (_, i) => ({
      id: i + 1,
      name: `项目 ${i + 1}`,
      author: `作者 ${i % 5 + 1}`,
      averageScore: Number((Math.random() * 5 + 5).toFixed(1))
    }))

    ratingList.value = mockData
    pagination.value.total = 30
  } catch (error) {
    ElMessage.error('获取评分列表失败')
    console.error(error)
  }
}

// 显示评分表单 -> 在提交的时候，会根据currentItem的值进行初始化
// 初始化评分项等于当前选中的item, 设置评分表单的评分和评论为0和空
// 设置评分表单对话框可见
const showRatingDialog = (item: RatingItem) => {
  currentItem.value = item
  ratingForm.value = {
    score: 0,
    comment: ''
  }
  ratingDialogVisible.value = true
}

// 显示评分详情
// 获取当前行的数据 & 设置详情对话框可见
const showRatingDetails = (id: number) => {
  currentItemId.value = id
  detailDialogVisible.value = true
}

// 提交评分
const submitRating = async () => {
  // 评分项不存在, 直接返回空
  if (!currentItem.value) return
  // 评分为0, 直接返回空
  if (ratingForm.value.score === 0) {
    ElMessage.warning('请先评分')
    return
  }
  try {
    // 模拟提交
    ElMessage.success('评分提交成功')
    // 1：关闭对话框
    ratingDialogVisible.value = false

    // 2：更新平均分
    // 2.1：获取当前评分项
    const item = ratingList.value.find(item => item.id === currentItem.value?.id)
    // 在评分项存在的情况下，更新平均分
    if (item) {
      item.averageScore = Number(((item.averageScore + ratingForm.value.score) / 2).toFixed(1))
    }
  } catch (error) {
    ElMessage.error('评分提交失败')
    console.error(error)
  }
}

// 每页条数变化
const handleSizeChange = (size: number) => {
  pagination.value.pageSize = size
  fetchRatingList()
}

// 初始化加载数据
onMounted(() => {
  fetchRatingList()
})
</script>

<style scoped>
.rating-container {
  padding: 20px;
}
.rating-card {
  margin-bottom: 20px;
}
.pagination {
  margin-top: 20px;
  justify-content: flex-end; /* 设置分页组件在容器中的位置为右对齐 */
}
.rating-form {
  padding: 0 20px; /* 添加内边距，使表单内容更靠左 */
}
</style>
